package com.bjsxt.commu2;

import java.util.LinkedList;
import java.util.List;

/**
 * 商品工厂类
 */
public class ProductFactory {

    //存储商品（增加、删除操作多，使用LinkedList效率更高）
    List<String> productList = new LinkedList<>();
    int max = 10;

    public ProductFactory() {
    }

    public ProductFactory(int max) {
        this.max = max;
    }

    //生产一件商品
    public synchronized void produce(String name) {

        //若库存已满，则生产者等待
        //若使用if，会导致生产者被唤醒后直接执行下面的代码，导致生产过多
        while (productList.size() == max) {
            try {
                //System.out.println("库存已满，生产者等待中...");
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        productList.add(name);
        System.out.println(Thread.currentThread().getName() + "生产了：" + name + "，当前库存：" + productList.size());

        //若库存已满，则通知消费者消费
        if (productList.size() == max) {
            //this.notify();      //随机唤醒一个线程，可能是消费者也可能是生产者
            this.notifyAll();   //唤醒所有线程，最好使用notifyAll，防止唤醒到生产者导致阻塞
        }

    }

    //消费一件商品
    public synchronized void consume() {

        //若库存为空，则消费者等待
        //若使用if，会导致消费者被唤醒后直接执行下面的代码，导致消费过多
        while (productList.size() == 0) {
            try {
                //System.out.println("库存为空，消费者等待中...");
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        String name = productList.remove(0);
        System.out.println(Thread.currentThread().getName() + "消费了：" + name + "，当前库存：" + productList.size());

        //若库存为空，则通知生产者生产
        if (productList.size() == 0) {
            //this.notify();     //随机唤醒一个线程，可能是消费者也可能是生产者
            this.notifyAll();   //唤醒所有线程，最好使用notifyAll，防止唤醒到消费者导致阻塞
        }
    }

}
